package com.kitty.game.equip.handler;

import com.kitty.game.role.model.Role;
import com.kitty.game.equip.model.RoleEquip;
import com.kitty.game.equip.model.RoleEquipField;
import com.kitty.game.attribute.config.Attribute;
import com.kitty.game.config.Equip;
import com.kitty.game.enter.FiedValue;
import com.kitty.game.equip.EquipDataPool;
import com.kitty.game.utils.AsktaoUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.text.DecimalFormat;
import java.text.MessageFormat;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Random;

import static com.kitty.game.utils.Const.MONEY_NAME;
import static com.kitty.game.utils.Const.ROLE_RESOURCE_NOT_ENOUGH;
import static com.kitty.game.utils.NotifyModules.NOTIFY_EQUIP_STRENGTHEN_OK;
import com.kitty.game.equip.handler.UpgradeHandler;

/**
 * 强化属性实现类
 */
@Component
@Slf4j
public abstract class StrengthenHandler extends UpgradeHandler {

    private static final String REQ_CRYSTAL = "超级圣水晶";

    private static final String ERROR_RESOURCES = "请放入正确的装备或材料。";

    private static final String MAX_FIELD = "#r{0}#n属性已强化至上限。";

    private static final String SUCCESS_MESSAGE = "恭喜你，花费{0}文钱，将#R{1}#n属性已强化成功。";

    private static final String FAIL_MESSAGE = "真遗憾，#R{0}#n属性已强化失败，当前进度#R{1}%#n，当进度达到#R100%#n强化必定成功。";


    /**
     * 取强化百分比属性
     */
    public abstract short getPercentId();

    /**
     * 取强化的部位
     */
    public abstract short getStrengthenField();

    @Override
    public String doUpgrade(Role role, Object... params) {
        RoleEquip crystal = (RoleEquip) params[0];
        RoleEquip roleEquip = (RoleEquip) params[1];
        Attribute attribute = (Attribute) params[2];
        boolean isUseLimit = (boolean) params[3];


        /**强化的进度*/
        LinkedHashMap<Short, FiedValue> percentMap = getPercentMap(roleEquip, attribute);
        /**强化的部位*/
        LinkedHashMap<Short, FiedValue> fieldMap = getFieldMap(roleEquip);

        /**要强化的属性当前值*/
        FiedValue fiedValue = getFieldValue(fieldMap, attribute);
        FiedValue percentValue = getFieldValueP(percentMap, attribute);
        int currField = attrService.getValue(fiedValue.getValue());
        /**要强化的属性当前进度值*/
        int currPercent = attrService.getValue(percentValue.getValue());
        /**要强化的属性的最大值*/

        int maxField = getMaxFieldByld(attribute.getAttrId(), roleEquip.queryLevel(), roleEquip.queryEquipPos(false));
        if (currField >= maxField) {
            return MessageFormat.format(MAX_FIELD, attribute.getValuename());
        }

        currPercent += (maxField - currField) * 0.75 * 100;
        /**扣钱*/
        int needCash = needCash(roleEquip.queryLevel(), roleEquip.queryColor());
        roleService.subtractMoney(role, needCash);

        /**删除圣水晶 Todo 黑水晶只在强化成功的时候删除*/
        int limitNum= equipService.delRoloEquip(REQ_CRYSTAL, 1, isUseLimit, role);
        if (limitNum > 0) {
            roleEquip.addLimitTime(limitNum);
        }

        Random random = new Random();
        int rate = random.nextInt(150000);
        int success = 10000;//成功率
        boolean isSuccess = false;
        if (currPercent >= success || (maxField - currField) * 500 >= success || (rate <= currPercent && currPercent > 5000)) {//完成度到100% 必定成功
            int value = random.nextInt(maxField - currField) + currField + 1;
            if (value < currField) value = currField;
            if (value > maxField) value = maxField;
            fiedValue.setValue((short) value);
            percentValue.setValue((short) 0);
            isSuccess = true;
            equipService.delEquipNum(role, crystal, 1);
        } else {
            percentValue.setValue((short) currPercent);
        }
        /**计算完美度*/
        equipService.countPerfect(roleEquip);

        refreshRoleEquip(role, roleEquip);

        if (isSuccess) {
            pushOperateResult(role, UPGRADE_SUCCESS);
            return MessageFormat.format(SUCCESS_MESSAGE, AsktaoUtil.getMoneyFormat(needCash), attribute.getValuename());
        } else {
            return MessageFormat.format(FAIL_MESSAGE, attribute.getValuename(), new DecimalFormat("#.00").format(currPercent / 100.0));
        }
    }

    @Override
    int getNotifyType() {
        return NOTIFY_EQUIP_STRENGTHEN_OK;
    }

    /**
     * 取被强化的属性
     */
    private FiedValue getFieldValue(LinkedHashMap<Short, FiedValue> fieldMap, Attribute attribute) {
        FiedValue result = null;
        for (Map.Entry<Short, FiedValue> entry : fieldMap.entrySet()) {
            if (entry.getKey() == attribute.getAttrId()) {
                result = entry.getValue();
                break;
            }
        }
        return result;
    }

    /**
     * 取被强化的属性的强化进度
     */
    private FiedValue getFieldValueP(LinkedHashMap<Short, FiedValue> fieldMap, Attribute attribute) {
        FiedValue result = null;
        for (Map.Entry<Short, FiedValue> entry : fieldMap.entrySet()) {
            if (entry.getKey() == attribute.getAttrId()) {
                result = entry.getValue();
                break;
            }
        }
        if (result == null) {
            result = new FiedValue();
            result.setType(attribute.getAttrId());
            result.setVT(attribute.getType());
            result.setValue(0);
            fieldMap.put(result.getType(), result);
        }
        return result;
    }

    private LinkedHashMap<Short, FiedValue> getFieldMap(RoleEquip roleEquip) {
        return roleEquip.getFields().get(getStrengthenField()).getField();
    }


    private LinkedHashMap<Short, FiedValue> getPercentMap(RoleEquip roleEquip, Attribute attribute) {
        LinkedHashMap<Short, FiedValue> percentMap = null;
        if (roleEquip.getFields().get(getPercentId()) != null) {
            percentMap = roleEquip.getFields().get(getPercentId()).getField();
        }
        if (percentMap == null) {
            percentMap = new LinkedHashMap<>();
            FiedValue fiedValue = new FiedValue();
            fiedValue.setType(attribute.getAttrId());
            fiedValue.setVT(attribute.getType());
            fiedValue.setValue(0);
            percentMap.put(fiedValue.getType(), fiedValue);
            RoleEquipField roleEquipField = new RoleEquipField();
            roleEquipField.setField(percentMap);
            roleEquip.getFields().put(getPercentId(), roleEquipField);
        }
        return percentMap;
    }


    @Override
    public String acceptUpgrade(Role role, int upgradePos, String param) {
        RoleEquip roleEquip = equipService.getRoleEquipByPos(role, upgradePos);
        if (roleEquip == null) {
            return "请放入正确的装备。";
        }
        if (!isRightPosition(roleEquip.queryEquipPos(false))) {
            return MessageFormat.format(NO_RIGHT_POSITION, "强化", roleEquip.getName());
        }
        Equip equip = EquipDataPool.getByName(roleEquip.getName());
        if (equip == null) {
            log.error("找不到装备配置ICON=[{}]", upgradePos);
            return MessageFormat.format(NOT_FIND_CONFIG, roleEquip.getName());
        }

        String[] params = param.split("\\|");
        /**黑水晶位置*/
        int crystalPos = Integer.parseInt(params[0]);
        RoleEquip crystal = equipService.getRoleEquipByPos(role, crystalPos);

        /**需要强化的属性名*/
        String attribName = params[1];
        Attribute attribute = attrService.getAttrByName(attribName);

        boolean isUseLimit = params[2].equals("1");

        String noEnough = checkResource(role, crystal, roleEquip, attribute, isUseLimit);
        if (noEnough != null) {
            return noEnough;
        }

        /**强化的部位*/
        LinkedHashMap<Short, FiedValue> fieldMap = getFieldMap(roleEquip);
        if (fieldMap == null) {
            return ERROR_RESOURCES;
        }

        return doUpgrade(role, crystal, roleEquip, attribute, isUseLimit);
    }

    /**
     * 判断黑水晶的属性是否匹配
     */

    @Override
    public String checkResource(Object... objects) {
        Role role = (Role) objects[0];
        RoleEquip crystal = (RoleEquip) objects[1];
        RoleEquip roleEquip = (RoleEquip) objects[2];
        Attribute attribute = (Attribute) objects[3];
        boolean isUseLimit = (boolean) objects[4];

        if (crystal == null || roleEquip == null) {
            return ERROR_RESOURCES;
        }
        if(crystal.queryEquipPos(true) !=roleEquip.queryEquipPos(false)){
            return ERROR_RESOURCES;
        }
        /**判断黑水晶的等级是否等于装备等级*/
        if (crystal.queryLevel() != roleEquip.queryLevel() - roleEquip.queryLevel() % 10) {
            return ERROR_RESOURCES;
        }

        int crystalNum = equipService.getCount(REQ_CRYSTAL, isUseLimit, role);

        if (crystalNum < 1) {
            return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, REQ_CRYSTAL);
        }

        /**判断要强化的属性是不是传入的黑水晶的属性*/
        FiedValue crystalField = crystal.getFields().get((short) 514).getField().get(attribute.getAttrId());
        FiedValue oldField = roleEquip.getFields().get(getStrengthenField()).getField().get(attribute.getAttrId());
        if (crystalField == null || oldField==null) {
            return ERROR_RESOURCES;
        }

        if (roleEquip.getType().equals("未鉴定装备")) {
            return ERROR_RESOURCES;
        }

        if (roleEquip.queryLevel() >= 70) {
            int needCash = needCash(roleEquip.queryLevel(), roleEquip.queryColor());
            if (role.getMoney() < needCash) {
                return MessageFormat.format(ROLE_RESOURCE_NOT_ENOUGH, MONEY_NAME);
            }
        }

        return null;
    }

    @Override
    public int needCash(short level, int pos) {
        return level < 70 ? 0 : 125100 + (level - 70) * (353100 - 125100) / 50;
    }

    private int needCash(short level, String color) {
        if (level < 70) {
            return 0;
        }
        if (color.equals("蓝色") || color.equals("粉色")) {
            return level * level * 16 + 5000;
        } else if (color.equals("金色") || color.equals("绿色")) {
            return level * level * 24 + 7500;
        } else {
            return 0;
        }
    }

    @Override
    public String getUpdateTypeStr() {
        return "equip_upgrade";
    }
}
